I want to add an object (from a different class) to an array in my class.
When I try to do that I get this
error: 0xC0000005: Access violation writing location
0x0000000000000000
I create the object (to be added) in the main function and I use the push method in the main function to add this object to my Parking_Lot class.
My code:
void Parking_Lot::push(Cars const &car)
{
time_t t = time(NULL);
struct tm Today = *localtime(&t);
if (is_full())
{
printf("Parking lot is full!!\n");
return;
}
if (Today.tm_hour < OpeningT.tm_hour && Today.tm_hour > ClosingT.tm_hour)
{
printf("Parking lot is now closed!!\n");
printf("Opening time: from %02d:%02d to %02d:%02d\n", OpeningT.tm_hour, OpeningT.tm_min, ClosingT.tm_hour, ClosingT.tm_min);
}
else if (Today.tm_hour == OpeningT.tm_hour || Today.tm_hour == ClosingT.tm_hour)
{
if(Today.tm_min > OpeningT.tm_min || Today.tm_min < ClosingT.tm_min) Lot[front++] = car;
else
{
printf("Parking lot is now closed!!\n");
printf("Opening time: from %02d:%02d to %02d:%02d\n", OpeningT.tm_hour, OpeningT.tm_min, ClosingT.tm_hour, ClosingT.tm_min);
}
}
else if(Today.tm_hour > OpeningT.tm_hour && Today.tm_hour < ClosingT.tm_hour) Lot[front++] = car;
}
where the car is the object I want to add and the Lot is the array in my class that I want to add the object to.
The constructor of my class:
Parking_Lot::Parking_Lot(int s)
{
Cars* Lot = new Cars[s+1];
size = s;
front = 0;
}
What am i doing wrong here and how can I fix it?
The problem is in your constructor:
Parking_Lot::Parking_Lot(int s)
{
Cars* Lot = new Cars[s+1];
size = s;
front = 0;
}
You define a new and separate variable Lot inside the constructor. It will not be related to any possible member variable you might have with the same name.
You need to initialize the member variable instead:
Parking_Lot::Parking_Lot(int s)
{
Lot = new Cars[s+1];
size = s;
front = 0;
}
Related
I am doing a project for nand2tetris. We write a program in Jack and test it on VMEmulator. The class looks like this:
class List {
field int data;
field List next;
/* Creates a new List object. */
constructor List new(int car, List cdr) {
let data = car;
let next = cdr;
return this;
}
/* Disposes this List by recursively disposing its tail. */
method void dispose() {
if (~(next = null)) {
do next.dispose();
}
// Use an OS routine to recycle the memory held by this object.
do Memory.deAlloc(this);
return;
}
/* Prints the list*/
method void print() {
do Output.printString(" -> ");
do Output.printInt(data);
if (~(next = null)) {
do next.print();
}
return;
}
/* Inserts the argument in the right position of the list (ascending order)*/
method void insertInOrder(int ins){
var List prev, curr, insert;
let prev = this;
let curr = prev.getnext();
while (ins > prev.getdata()){
if (ins < curr.getdata()){
let insert = List.new(ins, curr);
do prev.setnext(insert);
}
else{
let prev = prev.getnext();
let curr = prev.getnext();
}
}
return;
}
/* Searches the argument in the list, if found, it returns the corresponding List object*/
method List find(int toFind){
var List temp;
var List equal;
var boolean found;
let temp = this;
let found = false;
while (~(next = null)){
if(toFind = temp.getdata()){
let equal = temp;
let found = true;
}
let temp = temp.getnext();
}
if (found){
return equal;
}
else{
return null;
}
}
method List getnext(){
return next;
}
method void setnext(List object){
let next = object;
return;
}
method int getdata(){
return data;
}
}
It has one private variable data and a pointer next. So I wrote getter and setter method to return those values. Other methods are fine only the getdata()method is incorrect. When it runs through the VMEmulator, it shows the error Out of segment space in List.getdata.3. This shows in the VMEmulator.
0function List.getdata0
1push argument0
2pop pointer0
3push this 0
4return
the error is at the 4th line return. When I change the Jack code, the same error is still at the 4th line.
What exactly is the problem in my getter method?
When you run a VM program on the VMEmulator you must first manually set the pointers to the various segments, otherwise you may get an "Out of segment space" error.
To understand the necessary settings, look at what the corresponding .tst file does. An alternative method is to insert the proposed code inside a function, since the function call automatically makes this type of setting.
You can get this error when you try to access member data of an object which is not constructed. Could it be that the List cdr in the constructor was not properly constructed?
this simple code works fine and allows to add a BeginSample/EndSample call around each Update/LateUpdate/FixedUpdate function. However it doesn't take in consideration early return instructions, for example as result of a condition. Do you know how to write a similar function that take in considerations early returns so that the EndSample call will be executed under every circumstance?
Note that I am not a Cecil expert, I am just learning now. It appears to me that Cecil automatically updates the operations that returns early after calling InsertBefore and similar functions. So if a BR opcode was previously jumping to a specific instruction address, the address will be updated after the insertions in order to jump to the original instruction. This is OK in most of the cases, but in my case it means that an if statement would skip the last inserted operation as the BR operation would still point directly to the final Ret instruction. Note that Update, LateUpdate and FixedUpdate are all void functions.
foreach (var method in type.Methods)
{
if ((method.Name == "Update" || method.Name == "LateUpdate" || method.Name == "FixedUpdate") &&
method.HasParameters == false)
{
var beginMethod =
module.ImportReference(typeof (Profiler).GetMethod("BeginSample",
new[] {typeof (string)}));
var endMethod =
module.ImportReference(typeof (Profiler).GetMethod("EndSample",
BindingFlags.Static |
BindingFlags.Public));
Debug.Log(method.Name + " method found in class: " + type.Name);
var ilProcessor = method.Body.GetILProcessor();
var first = method.Body.Instructions[0];
ilProcessor.InsertBefore(first,
Instruction.Create(OpCodes.Ldstr,
type.FullName + "." + method.Name));
ilProcessor.InsertBefore(first, Instruction.Create(OpCodes.Call, beginMethod));
var lastRet = method.Body.Instructions[method.Body.Instructions.Count - 1];
ilProcessor.InsertBefore(lastRet, Instruction.Create(OpCodes.Call, endMethod));
changed = true;
}
}
as a Bonus, if you can explain to me the difference between Emit and Append a newly created instruction with the same operand. does Append execute an Emit under the hood or does something more?
I may have found the solution, at least apparently it works. I followed the code used to solve a similar problem from here:
https://groups.google.com/forum/#!msg/mono-cecil/nE6JBjvEFCQ/MqV6tgDCB4AJ
I adapted it for my purposes and it seemed to work, although I may find out other issues. This is the complete code:
static bool ProcessAssembly(AssemblyDefinition assembly)
{
var changed = false;
var moduleG = assembly.MainModule;
var attributeConstructor =
moduleG.ImportReference(
typeof(RamjetProfilerPostProcessedAssemblyAttribute).GetConstructor(Type.EmptyTypes));
var attribute = new CustomAttribute(attributeConstructor);
var ramjet = moduleG.ImportReference(typeof(RamjetProfilerPostProcessedAssemblyAttribute));
if (assembly.HasCustomAttributes)
{
var attributes = assembly.CustomAttributes;
foreach (var attr in attributes)
{
if (attr.AttributeType.FullName == ramjet.FullName)
{
Debug.LogWarning("<color=yellow>Skipping already-patched assembly:</color> " + assembly.Name);
return false;
}
}
}
assembly.CustomAttributes.Add(attribute);
foreach (var module in assembly.Modules)
{
foreach (var type in module.Types)
{
// Skip any classes related to the RamjetProfiler
if (type.Name.Contains("AssemblyPostProcessor") || type.Name.Contains("RamjetProfiler"))
{
// Todo: use actual type equals, not string matching
Debug.Log("Skipping self class : " + type.Name);
continue;
}
if (type.BaseType != null && type.BaseType.FullName.Contains("UnityEngine.MonoBehaviour"))
{
foreach (var method in type.Methods)
{
if ((method.Name == "Update" || method.Name == "LateUpdate" || method.Name == "FixedUpdate") &&
method.HasParameters == false)
{
var beginMethod =
module.ImportReference(typeof(Profiler).GetMethod("BeginSample",
new[] { typeof(string) }));
var endMethod =
module.ImportReference(typeof(Profiler).GetMethod("EndSample",
BindingFlags.Static |
BindingFlags.Public));
Debug.Log(method.Name + " method found in class: " + type.Name);
var ilProcessor = method.Body.GetILProcessor();
var first = method.Body.Instructions[0];
ilProcessor.InsertBefore(first,
Instruction.Create(OpCodes.Ldstr,
type.FullName + "." + method.Name));
ilProcessor.InsertBefore(first, Instruction.Create(OpCodes.Call, beginMethod));
var lastcall = Instruction.Create(OpCodes.Call, endMethod);
FixReturns(method, lastcall);
changed = true;
}
}
}
}
}
return changed;
}
static void FixReturns(MethodDefinition med, Instruction lastcall)
{
MethodBody body = med.Body;
var instructions = body.Instructions;
Instruction formallyLastInstruction = instructions[instructions.Count - 1];
Instruction lastLeaveInstruction = null;
var lastRet = Instruction.Create(OpCodes.Ret);
instructions.Add(lastcall);
instructions.Add(lastRet);
for (var index = 0; index < instructions.Count - 1; index++)
{
var instruction = instructions[index];
if (instruction.OpCode == OpCodes.Ret)
{
Instruction leaveInstruction = Instruction.Create(OpCodes.Leave, lastcall);
if (instruction == formallyLastInstruction)
{
lastLeaveInstruction = leaveInstruction;
}
instructions[index] = leaveInstruction;
}
}
FixBranchTargets(lastLeaveInstruction, formallyLastInstruction, body);
}
private static void FixBranchTargets(
Instruction lastLeaveInstruction,
Instruction formallyLastRetInstruction,
MethodBody body)
{
for (var index = 0; index < body.Instructions.Count - 2; index++)
{
var instruction = body.Instructions[index];
if (instruction.Operand != null && instruction.Operand == formallyLastRetInstruction)
{
instruction.Operand = lastLeaveInstruction;
}
}
}
basically what it does is to add a Ret instuction, but then replace all the previous Ret (usually one, why should it be more than one?) with a Leave function (don't even know what it means :) ), so that all the previous jumps remain valid. Differently than the original code, I make the Leave instruction point to the EndSample call before the last Ret
I am am trying to call a variable in another method to my array.
var Com = the difficulty for the game. But the method below I'm trying to call the var Com, for: var c = Com.GetChoice();
Not sure why I can not figure out how to call it.
public object SetDiff()
{
Console.WriteLine("Enter difficulty #: (1 = Easy, 2 = Normal, 3 = Impossible)");
var diff = Console.ReadLine();
int mode;
int.TryParse(diff, out mode);
if (mode == 1)
{
Console.Clear();
var Com = new Easy();
return Com;
}
if (mode == 2)
{
Console.Clear();
var Com = new Medium();
return Com;
}
if (mode == 3)
{
Console.Clear();
var Com = new Hard();
return Com;
}
else
{
Console.WriteLine("That is not a valid input.");
return SetDiff();
}
} // Apparently you can't set variables in a switch.
public int[] FaceOff(int num)
{
int PlayerWin = 0;
int ComWin = 0;
int Tie = num + 1;
// TODO : Get rid of TIES!
for (int i = 0; i < num; i++)
{
var p = p1.GetChoice();
var c = Com.GetChoice();
You have many different options:
Pass as parameter
public int[] FaceOff(int num, int Com){...}
make a "global" variable
private int Com;
I would also recommend you to learn OOP (Object Orientated Programming) basics.
I'm new to wxWidgets, although I've been able to get an application up and running fairly smoothly up until this point. For the main window, I'm using a wxGrid inside a wxPanel. Everything runs fine until I close the program.
Thanks in advance for any insight.
The grid is a member of a class derived from wxPanel:
class FormDataView
: public wxPanel
{
public:
FormDataView(wxWindow* parent);
virtual ~FormDataView();
private:
wxGrid* grid_;
}
And created in the constructor. The data for the grid comes from another thread, so I create a custom event for actually writing the data.
wxDEFINE_EVENT(FORMDATAVIEW_UPDATE, wxThreadEvent);
FormDataView::FormDataView(wxWindow* parent)
: wxPanel(parent,wxID_ANY )
{
wxBoxSizer* mbox = new wxBoxSizer(wxVERTICAL);
grid_ = new wxGrid(this, wxID_ANY );
grid_->CreateGrid(0, 0);
mbox->Add(grid_,wxSizerFlags(1).Expand());
Bind(FORMDATAVIEW_UPDATE, &FormDataView::onDataUpdate, this);
}
///
/// This function is called by a child thread when data is received.
///
void
FormDataView::onDataReceived(IFORMATTERBASE_PFONDATARECEIVED_ARGS)
{
newHeaders_ = headers;
newData_ = data;
wxThreadEvent* evt = new wxThreadEvent(FORMDATAVIEW_UPDATE);
evt->SetString("Yo.");
wxQueueEvent(this, evt);
}
///
/// Called by the event loop. This function puts the data
/// into the grid.
///
void
FormDataView::onDataUpdate(wxThreadEvent& evt)
{
FormatterStringList& headers = newHeaders_;
FormatterStringList& data = newData_;
if (grid_->GetNumberRows() <= 0)
{
wxGridCellAttr* attr = new wxGridCellAttr();
attr->SetReadOnly(true);
attr->SetAlignment(wxALIGN_CENTRE, wxALIGN_CENTRE);
for (size_t i = 0; i<headers.size(); ++i)
{
if (grid_->GetNumberCols() <= 0)
grid_->InsertCols();
else
grid_->AppendCols();
grid_->SetColLabelValue(i, headers[i].data());
grid_->SetColAttr(i, attr);
}
}
// suspend redrawing while we add data.
grid_->BeginBatch();
// insert a new row at the top of the table
grid_->InsertRows(
0, // position
1, // number of rows to insert
true); // update labels (not current used)
for (size_t i = 0; i<headers.size(); ++i)
{
if (data.size() < i)
{
grid_->SetCellValue(0, i, "");
}
else
{
grid_->SetCellValue(0, i, data[i].data());
}
}
// resume redrawing.
grid_->EndBatch();
}
Everything runs fine, but when I close, I get the following message. I've indicated the line upon which the breakpoint occurs. Is there some short of sequence for clearing data out of the grid I'm supposed to follow?
wxGrid::CellSpan
wxGrid::GetCellSize( int row, int col, int *num_rows, int *num_cols ) const
{
wxGridCellAttr *attr = GetCellAttr(row, col);
attr->GetSize( num_rows, num_cols );
attr->DecRef();
>>>>>>> if ( *num_rows == 1 && *num_cols == 1 )
return CellSpan_None; // just a normal cell
if ( *num_rows < 0 || *num_cols < 0 )
return CellSpan_Inside; // covered by a multi-span cell
// this cell spans multiple cells to its right/bottom
return CellSpan_Main;
}
The problem was with where I was creating the column attribute. I was re-using the same column attribute instance for every column, but each column needs to have its own instance.
BEFORE:
if (grid_->GetNumberRows() <= 0)
{
///
/// NO! The columns will share the same cell attribute
/// instance.
///
wxGridCellAttr* attr = new wxGridCellAttr();
attr->SetReadOnly(true);
attr->SetAlignment(wxALIGN_CENTRE, wxALIGN_CENTRE);
for (size_t i = 0; i<headers.size(); ++i)
{
if (grid_->GetNumberCols() <= 0)
grid_->InsertCols();
else
grid_->AppendCols();
grid_->SetColLabelValue(i, headers[i].data());
grid_->SetColAttr(i, attr);
}
}
CORRECT:
if (grid_->GetNumberRows() <= 0)
{
for (size_t i = 0; i<headers.size(); ++i)
{
if (grid_->GetNumberCols() <= 0)
grid_->InsertCols();
else
grid_->AppendCols();
grid_->SetColLabelValue(i, headers[i].data());
///
/// Each column will have its own cell attribute.
/// Supposedly, the column will take ownership of this
/// instance.
///
wxGridCellAttr* attr = new wxGridCellAttr();
attr->SetReadOnly(true);
attr->SetAlignment(wxALIGN_CENTRE, wxALIGN_CENTRE);
grid_->SetColAttr(i, attr);
}
}
I have a sample hive table created as
CREATE TABLE union_test(foo UNIONTYPE<int, double, array<string>, struct<a:int,b:string>>);
The data can be viewed as
SELECT foo FROM union_test;
The output is
{0:1}
{1:2.0}
{2:["three","four"]}
{3:{"a":5,"b":"five"}}
{2:["six","seven"]}
{3:{"a":8,"b":"eight"}}
{0:9}
{1:10.0}
the first field (tag) denotes the type of the union ( 0 for int, 1 for double, 2 for array etc).
My problem is if I found to select only those records where the union type is 2 (array), how should I frame my query?
There is no function in Hive to read data from UnionType. So i wrote 2 UDF´s. One to get Union tag (that you trying to do) and second to get struct from union as an example.
get_union_tag() function:
package HiveUDF;
import org.apache.hadoop.hive.ql.exec.Description;
import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.UnionObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
#Description(name = "get_union_tag", value = "_FUNC_(unionObject)"
+ " - Returns union object Tag", extended = "Example:\n" + " > SELECT _FUNC_(unionObject) FROM src LIMIT 1;\n one")
public class GetUnionTag extends GenericUDF {
// Global variables that inspect the input.
// These are set up during the initialize() call, and are then used during the
// calls to evaluate()
private transient UnionObjectInspector uoi;
#Override
// This is what we do in the initialize() method:
// Verify that the input is of the type expected
// Set up the ObjectInspectors for the input in global variables
// Return the ObjectInspector for the output
public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
// Verify the input is of the required type.
// Set the global variables (the various ObjectInspectors) while we're doing this
// Exactly one input argument
if( arguments.length != 1 ){
throw new UDFArgumentLengthException("_FUNC_(unionObject) accepts exactly one argument.");
}
// Is the input an array<>
if( arguments[0].getCategory() != ObjectInspector.Category.UNION ){
throw new UDFArgumentTypeException(0,"The single argument to AddExternalIdToPurchaseDetails should be "
+ "Union<>"
+ " but " + arguments[0].getTypeName() + " is found");
}
// Store the ObjectInspectors for use later in the evaluate() method
uoi = ((UnionObjectInspector)arguments[0]);
// Set up the object inspector for the output, and return it
return PrimitiveObjectInspectorFactory.javaByteObjectInspector;
}
#Override
public Object evaluate(DeferredObject[] arguments) throws HiveException {
byte tag = uoi.getTag(arguments[0].get());
return tag;
}
#Override
public String getDisplayString(String[] children) {
StringBuilder sb = new StringBuilder();
sb.append("get_union_tag(");
for (int i = 0; i < children.length; i++) {
if (i > 0) {
sb.append(',');
}
sb.append(children[i]);
}
sb.append(')');
return sb.toString();
}
}
function get_struct_from_union() UDF :
package HiveUDF;
import org.apache.hadoop.hive.ql.exec.Description;
import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.StructObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.UnionObjectInspector;
#Description(name = "get_union_struct", value = "_FUNC_(unionObject)"
+ " - Returns struct ", extended = "Example:\n" + " > _FUNC_(unionObject).value \n 90.0121")
public class GetUnionStruct extends GenericUDF {
// Global variables that inspect the input.
// These are set up during the initialize() call, and are then used during the
// calls to evaluate()
//
// ObjectInspector for the list (input array<>)
// ObjectInspector for the struct<>
// ObjectInspectors for the elements of the struct<>, target, quantity and price
private UnionObjectInspector unionObjectInspector;
private StructObjectInspector structObjectInspector;
#Override
// This is what we do in the initialize() method:
// Verify that the input is of the type expected
// Set up the ObjectInspectors for the input in global variables
// Return the ObjectInspector for the output
public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
// Verify the input is of the required type.
// Set the global variables (the various ObjectInspectors) while we're doing this
// Exactly one input argument
if( arguments.length != 1 ){
throw new UDFArgumentLengthException("_FUNC_(unionObject) accepts exactly one argument.");
}
// Is the input an array<>
if( arguments[0].getCategory() != ObjectInspector.Category.UNION ){
throw new UDFArgumentTypeException(0,"The single argument to AddExternalIdToPurchaseDetails should be "
+ "Union<Struct>"
+ " but " + arguments[0].getTypeName() + " is found");
}
// Set up the object inspector for the output, and return it
return structObjectInspector;
}
#Override
public Object evaluate(DeferredObject[] arguments) throws HiveException {
return ((UnionObjectInspector) unionObjectInspector).getField(arguments[0].get());
}
#Override
public String getDisplayString(String[] children) {
StringBuilder sb = new StringBuilder();
sb.append("get_union_vqtstruct(");
for (int i = 0; i < children.length; i++) {
if (i > 0) {
sb.append(',');
}
sb.append(children[i]);
}
sb.append(')');
return sb.toString();
}
}
to use these UDF´s compile and create jar file. Than upload into hive (in my case HDInsight). Than just use
add jar wasb:///hive/HiveGUDF.jar;
CREATE TEMPORARY FUNCTION get_union_struct AS 'HiveUDF.GetUnionStruct';
before u run e.g.
SELECT get_union_tag(exposed) FROM test;